#import "PolyvVideoController.h"
#import <PLVVodSDK/PLVVodSDK.h>
#import "PLVVodSkinPlayerController.h"
#import <IJKMediaFramework/IJKMediaFramework.h>
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import "PLVTimer.h"

#ifdef DEBUG
#   define DLog(fmt, ...) NSLog((@"%s [Line %d] [Native打印]" fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define DLog(...)
#endif

@interface PolyvVideoController()
@property (strong, nonatomic) UISlider *volumeSlider;
/// 播放刷新定时器
@property (nonatomic, strong) PLVTimer *playbackTimer;
@end

@implementation PolyvVideoController {
    UIView * _videoView;
    int64_t _viewId;
    FlutterMethodChannel* _channel;
    
    PLVVodSkinPlayerController *_vodPlayer;//点播播放器
//    NSString * _config;
    PLVVodLocalVideo *_localVideo;//本地视频模型
    PLVVodVideo *_videoModel;//视频模型
//    DPLiveNoNetView *_noNetView;//播放器无网络view
    NSString *_vid;
    
    BOOL _isNeedCreatePlayer;//是否需要创建播放器

//    UISlider *_volumeSlider;                //音量
}

#pragma mark - life cycle
- (instancetype)initWithWithFrame:(CGRect)frame
                   viewIdentifier:(int64_t)viewId
                        arguments:(id _Nullable)args
                  binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
    if (self = [super init]) {
        _viewId = viewId;
        _isNeedCreatePlayer = YES;
        
        // 注册flutter 与 ios 通信通道
        NSString* channelName = [NSString stringWithFormat:@"polyv_video_plugin_%lld", viewId];
        _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];

//        NSString * config = @"config";
//        if ([args isKindOfClass:[NSDictionary class]]) {
//            NSDictionary *params = (NSDictionary *)args;
//            [[params allKeys] containsObject:@"config"] ? [[params valueForKey:@"config"] isKindOfClass:[NSString class]] ? _config = [params valueForKey:@"config"] : nil : nil;
//        }
//        DLog(@"_config >>> %@",_config);
        
        _videoView = [[UIView alloc] initWithFrame:frame];
        _videoView.backgroundColor = UIColor.blackColor;
        
//        //使用 PLVVodSettings 进行初始化
//        [self initPLVVodSettings:_config];
        
        [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_DEBUG];
        [self addVodPlayer];
        
        MPVolumeView *volumeView = [MPVolumeView new];
        volumeView.frame = CGRectMake(-1000, -1000, 100, 100);
        volumeView.hidden = NO;
        for (UIView *view in [volumeView subviews]){
            if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
                self.volumeSlider = (UISlider*)view;
                break;
            }
        }
        [_videoView addSubview:volumeView];
        
        __weak __typeof__(self) weakSelf = self;
        [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
            [weakSelf handleMethodCall:call result:result];
        }];
    }
    return self;
}

- (UIView *)view{
    return _videoView;
}

//// 使用 PLVVodSettings 进行初始化
//- (void)initPLVVodSettings:(NSString *)configString{
//    NSError *error = nil;
//    PLVVodSettings *settings = [PLVVodSettings settingsWithConfigString:configString error:&error];
//    settings.logLevel = PLVVodLogLevelAll;
//    settings.mutilAccount = YES;
//    [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_DEBUG];
//
//    [self addVodPlayer];
//}

// 添加播放器
- (void)addVodPlayer{
    if(!_vodPlayer) _vodPlayer = [[PLVVodSkinPlayerController alloc] initWithNibName:nil bundle:nil];
    _isNeedCreatePlayer = NO;
    UIViewController *vc = [[UIViewController alloc] init];
    [_videoView addSubview:vc.view];
    [_vodPlayer addPlayerOnPlaceholderView:_videoView rootViewController:vc];
    _vodPlayer.isGesture = NO;
    _vodPlayer.rememberLastPosition = NO;
    _vodPlayer.enableBackgroundPlayback= NO;
    if (_localVideo) {
        _vodPlayer.video = _localVideo;
    }
//#pragma mark callbackmethod test-----
//    [self configCallBackBlock];
    
//    _vid = @"ef4825bc7ea2f38b0ca32dfcf0308f21_e";
//    [self startPlayWithVid:_vid];
    
    __weak typeof(self)weakSelf = self;
    // 加载状态回调
    _vodPlayer.loadStateHandler = ^(PLVVodPlayerViewController *player) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if(player.loadState==4){
            DLog(@"加载状态 +++++++");
        }else{
            DLog(@"加载状态 ------- %lu", (unsigned long)player.loadState);
        }
        
        // 开始能够获取到播放器的总时长
        NSDictionary *dict = @{
            @"type":@"onInfo",
        };
        [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
    };
    
    // 播放器是否就绪
    _vodPlayer.preparedToPlayHandler = ^(PLVVodPlayerViewController *player) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if(player.preparedToPlay){
            DLog(@"视频加载就绪 !");
            NSDictionary *dict = @{
                @"type":@"onPrepared",
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        }
    };
}

//// 播放视频
//- (void)startPlayWithVid:(NSString *)vid{
//    _vid = [vid stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
//    if (_vid.length) {
//        __weak typeof(self) weakSelf = self;
//        [PLVVodVideo requestVideoWithVid:vid completion:^(PLVVodVideo *video, NSError *error) {
//            __strong typeof(weakSelf) strongSelf = weakSelf;
//            strongSelf->_vodPlayer.video = video;
//        }];
//    }
//}

//- (void)setVideoModel:(PLVVodVideo *)video {
////    _video = video;
//    dispatch_async(dispatch_get_main_queue(), ^{
//        self->_vodPlayer.video = video;
//    });
//}


- (void)startPlayWithVid:(NSString *)vid{
    __weak typeof(self)weakSelf = self;
    if (vid && vid.length>0){
        __strong typeof(weakSelf) strongSelf = weakSelf;
        // 默认有网络
        strongSelf->_localVideo = [PLVVodLocalVideo localVideoWithVid:vid dir:[PLVVodDownloadManager sharedManager].downloadDir];
        if (strongSelf->_localVideo == nil){
            [PLVVodVideo requestVideoWithVid:vid completion:^(PLVVodVideo *video, NSError *error) {
                if (!video.available){
                    // 视频无效
                    DLog(@"获取视频无效");
                }else{
                    // 获取到有效视频
                    strongSelf->_videoModel = video;
                }

                //是否第一次建播放器
                if (strongSelf->_isNeedCreatePlayer) {
                    if(!strongSelf->_vodPlayer) strongSelf->_vodPlayer = [[PLVVodSkinPlayerController alloc] initWithNibName:nil bundle:nil];
                    [strongSelf->_vodPlayer setVideo:video quality:video.preferredQuality];
                    strongSelf->_isNeedCreatePlayer = NO;
                }else{
                    [strongSelf->_vodPlayer setVideo:video];
                }

                strongSelf->_localVideo  = [PLVVodLocalVideo localVideoWithVideo:video dir:[PLVVodDownloadManager sharedManager].downloadDir];
            }];
        }else{
            DLog(@"本地视频");
            __strong typeof(weakSelf) strongSelf = weakSelf;
            strongSelf->_vodPlayer.video = strongSelf->_localVideo;
            [strongSelf->_vodPlayer setVideo:strongSelf->_localVideo];
            [strongSelf->_vodPlayer setURL:[NSURL URLWithString:strongSelf->_localVideo.play_source_url]];
            [strongSelf->_vodPlayer play];
            
        }
        
        dispatch_async(dispatch_get_main_queue(), ^{
//            __weak typeof(strongSelf)weakSelf
            strongSelf->_vodPlayer.gestureCallback = ^(PLVVodPlayerViewController *player, UIGestureRecognizer *recognizer, PLVVodGestureType gestureType) {
                [weakSelf handleGesture:recognizer gestureType:gestureType];
            };
        });
        
        self.playbackTimer = [PLVTimer repeatWithInterval:1 repeatBlock:^{
            dispatch_async(dispatch_get_main_queue(), ^{
                __strong typeof(weakSelf) strongSelf = weakSelf;
                NSDictionary *dict1 = @{
                    @"type":@"onCurrentPosition",
                    @"vid":vid,
                    @"currentPositionMs":[[strongSelf getCurrentPlaybackTime] stringValue],
                };
                [strongSelf->_channel invokeMethod:@"listener" arguments:dict1];
                NSDictionary *dict2 = @{
                    @"type":@"onBufferingUpdate",
                    @"percent":[[strongSelf getPlayableDuration] stringValue],
                };
                [strongSelf->_channel invokeMethod:@"listener" arguments:dict2];
            });
        }];
        
        /// 播放结束回调
        _vodPlayer.reachEndHandler = ^(PLVVodPlayerViewController *player) {
            DLog(@"播放结束回调");
            NSDictionary *dict = @{
                @"type":@"onCompletion",
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        };
        
        /// 播放器错误回调
        _vodPlayer.playerErrorHandler = ^(PLVVodPlayerViewController *player, NSError *error) {
            DLog(@"播放器错误回调");
            NSDictionary *dict = @{
                @"type":@"onVideoPlayError",
                @"msg":error.description,
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        };
        
        /// 播放状态回调
        _vodPlayer.playbackStateHandler = ^(PLVVodPlayerViewController *player) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            if(player.playbackState == PLVVodPlaybackStatePlaying){
                DLog(@"播放状态回调 - onPlay");
//                [strongSelf.playbackTimer resume];
                NSDictionary *dict = @{
                    @"type":@"onPlay",
                };
                [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
            }else if(player.playbackState == PLVVodPlaybackStatePaused){
                DLog(@"播放状态回调 - onPause");
//                [strongSelf.playbackTimer pause];
                NSDictionary *dict = @{
                    @"type":@"onPause",
                };
                [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
            }
        };
        
    }else{
        DLog(@"vid 参数不符合要求!");
    }
}

#pragma mark gesture
- (void)handleGesture:(UIGestureRecognizer *)recognizer gestureType:(PLVVodGestureType)gestureType {
    __weak typeof(self)weakSelf = self;
    switch (gestureType) {
        case PLVVodGestureTypeTap:{
//            DLog(@"单击...");
            __strong typeof(weakSelf) strongSelf = weakSelf;
            NSDictionary *dict = @{
                @"type":@"click",
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        }break;
        case PLVVodGestureTypeDoubleTap:{
//            DLog(@"双击...");
            __strong typeof(weakSelf) strongSelf = weakSelf;
            NSDictionary *dict = @{
                @"type":@"doubleClick",
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        }break;
        case PLVVodGestureTypeLeftSideUpPan:{
            DLog(@"左侧上滑...");
            __strong typeof(weakSelf) strongSelf = weakSelf;
            NSDictionary *dict = @{
                @"type":@"leftUp",
                @"start":recognizer.state == UIGestureRecognizerStateBegan?@YES:@NO,
                @"end":recognizer.state == UIGestureRecognizerStateEnded?@YES:@NO
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        }break;
        case PLVVodGestureTypeLeftSideDownPan:{
            DLog(@"左侧下滑...");
            __strong typeof(weakSelf) strongSelf = weakSelf;
            NSDictionary *dict = @{
                @"type":@"leftDown",
                @"start":recognizer.state == UIGestureRecognizerStateBegan?@YES:@NO,
                @"end":recognizer.state == UIGestureRecognizerStateEnded?@YES:@NO
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        }break;
        case PLVVodGestureTypeRightSideUpPan:{
            DLog(@"右侧上滑...");
            __strong typeof(weakSelf) strongSelf = weakSelf;
            NSDictionary *dict = @{
                @"type":@"rightUp",
                @"start":recognizer.state == UIGestureRecognizerStateBegan?@YES:@NO,
                @"end":recognizer.state == UIGestureRecognizerStateEnded?@YES:@NO
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        }break;
        case PLVVodGestureTypeRightSideDownPan:{
            DLog(@"右侧下滑...");
            __strong typeof(weakSelf) strongSelf = weakSelf;
            NSDictionary *dict = @{
                @"type":@"rightDown",
                @"start":recognizer.state == UIGestureRecognizerStateBegan?@YES:@NO,
                @"end":recognizer.state == UIGestureRecognizerStateEnded?@YES:@NO
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        }break;
        case PLVVodGestureTypeLeftPan:{
            DLog(@"左滑...");
            __strong typeof(weakSelf) strongSelf = weakSelf;
            NSDictionary *dict = @{
                @"type":@"swipeLeft",
                @"start":recognizer.state == UIGestureRecognizerStateBegan?@YES:@NO,
                @"end":recognizer.state == UIGestureRecognizerStateEnded?@YES:@NO
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        }break;
        case PLVVodGestureTypeRightPan:{
            DLog(@"右滑...");
            __strong typeof(weakSelf) strongSelf = weakSelf;
            NSDictionary *dict = @{
                @"type":@"swipeRight",
                @"start":recognizer.state == UIGestureRecognizerStateBegan?@YES:@NO,
                @"end":recognizer.state == UIGestureRecognizerStateEnded?@YES:@NO
            };
            [strongSelf->_channel invokeMethod:@"listener" arguments:dict];
        }break;
        default:{}break;
    }
}

-(void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result{
    if ([[call method] isEqualToString:@"setVid"]) {
        NSDictionary *argsMap = call.arguments;
        _vid = argsMap[@"vid"];
        [self startPlayWithVid:_vid];
        result(nil);
    }else if([[call method] isEqualToString:@"pause"]) {
        [_vodPlayer pause];
    }else if ([[call method] isEqualToString:@"resume"]) {
        [_vodPlayer play];
    }else if ([[call method] isEqualToString:@"setVideoURI"]) {
        NSDictionary *argsMap = call.arguments;
        NSString *url = argsMap[@"url"];
        [_vodPlayer setURL:[NSURL URLWithString:url]];
        [_vodPlayer play];
        result(nil);
    }else if ([[call method] isEqualToString:@"init"]) {
        result(nil);
    }else if ([[call method] isEqualToString:@"stop"]) {
        result(nil);
    }else if([[call method] isEqualToString:@"brightness"]) { // 获取亮度
        result([self onBrightness]);
    }else if([[call method] isEqualToString:@"volume"]) { // 获取音量
        result([self onGetVolume]);
    }else if([[call method] isEqualToString:@"setBrightness"]) { // 设置亮度
        [self onSetBrightness:call result:result];
    }else if([[call method] isEqualToString:@"setVolume"]) { // 设置音量
        [self onSetVolume:call result:result];
    }else if ([[call method] isEqualToString:@"destroy"]) {
        [self.playbackTimer cancel];
        self.playbackTimer = nil;
        [_vodPlayer pause];
        _vodPlayer = nil;
    }else if ([[call method] isEqualToString:@"start"]) {
        [_vodPlayer play];
        result(nil);
    }else if ([[call method] isEqualToString:@"isPlaying"]) { // 是否播放中
        result(_vodPlayer.playbackState == PLVVodPlaybackStatePlaying ? @YES : @NO);
    }else if ([[call method] isEqualToString:@"duration"]) { // 总时长
        NSNumber *point = [self getDuration];
        result(point);
    }else if ([[call method] isEqualToString:@"currentPosition"]) { // 当前节点
        NSNumber *point = [self getCurrentPlaybackTime];
        result(point);
    }else if ([[call method] isEqualToString:@"bufferPercentage"]) { // 缓冲百分比
        NSNumber *point = [self getPlayableDuration];
        result(point);
    }else if ([[call method] isEqualToString:@"seekTo"]) {  // 跳转某节点
//        [self.playbackTimer pause];
        NSDictionary *argsMap = call.arguments;
        NSString *point = argsMap[@"progress"];
        _vodPlayer.currentPlaybackTime = point.doubleValue/1000.0;
        [_vodPlayer play];
        result(nil);
    }else if ([[call method] isEqualToString:@"playRate"]) { // 获取播放速度
        NSNumber *rate = [NSNumber numberWithDouble:_vodPlayer.playbackRate];
        result(rate);
    }else if ([[call method] isEqualToString:@"setPlayRate"]) { // 设置播放速度
        NSDictionary *argsMap = call.arguments;
        NSString *rate = argsMap[@"rate"];
        _vodPlayer.playbackRate = rate.doubleValue;
        result(nil);
    }else if ([[call method] isEqualToString:@"qualityCount"]) { // 获取可用清晰度数量
        NSNumber *num = [NSNumber numberWithInt:_vodPlayer.video.qualityCount];
        result(num);
    }else if ([[call method] isEqualToString:@"preferredQuality"]) { // 获取视频默认清晰度
        NSNumber *preferredQuality = [NSNumber numberWithDouble:_vodPlayer.video.preferredQuality];
        result(preferredQuality);
    }else if ([[call method] isEqualToString:@"currentQuality"]) { // 获取清晰度
        NSNumber *preferredQuality = [NSNumber numberWithDouble:_vodPlayer.quality];
        result(preferredQuality);
    }else if ([[call method] isEqualToString:@"setQuality"]) { // 设置清晰度
        NSDictionary *argsMap = call.arguments;
        NSString *quality = argsMap[@"quality"];
        [_vodPlayer switchQuality:quality.doubleValue];
        result(nil);
    }else {
        result(FlutterMethodNotImplemented);
    }
}

// 总时长
- (NSNumber *)getDuration {
    return [NSNumber numberWithInt:(_vodPlayer.duration*1000)];
}
// 当前节点
- (NSNumber *)getCurrentPlaybackTime {
    return [NSNumber numberWithInt:_vodPlayer.currentPlaybackTime*1000];
}
// 缓冲百分比
- (NSNumber *)getPlayableDuration {
    return [NSNumber numberWithInt:_vodPlayer.playableDuration*100/_vodPlayer.duration];
}

- (NSNumber *)onBrightness {
    float tmp = [UIScreen mainScreen].brightness * 100;
    int a = (int)lroundf(tmp);
//    DLog(@"[LiveView打印2] 当前亮度>>>>> %d",a);
    return [NSNumber numberWithInt:a];
}
- (void)onSetBrightness:(FlutterMethodCall*)call result:(FlutterResult)result {
    NSDictionary *argsMap = call.arguments;
    int brightness = [argsMap[@"brightness"] intValue];
    float tmp = brightness / 100.0;
//    DLog(@"[LiveView打印] 亮度settings >>>>> %f",tmp);
    [[UIScreen mainScreen] setBrightness:tmp];
}
- (NSNumber *)onGetVolume {
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    float tmp = audioSession.outputVolume * 100;
    int a = (int)lroundf(tmp);
    return [NSNumber numberWithInt:a];
}
- (void)onSetVolume:(FlutterMethodCall*)call result:(FlutterResult)result {
    NSDictionary *argsMap = call.arguments;
    int volumeValue = [argsMap[@"volume"] intValue];
    if (volumeValue > 100) volumeValue = 100;
    if (volumeValue < 0) volumeValue = 0;
    float tmp = volumeValue / 100.0;
    [self.volumeSlider setValue:tmp animated:NO];
}


@end
